Rappel imagé des dimensions existantes dans un graphique
Quelles dimensions utiliser pour les petits multiples ?
Avec une dimension (une variable), on peut déjà faire un graphique
On peut également adapter la géométrie en fonction de ce qu’on veut montrer
On retrouve généralement, au moins, les dimensions cartésiennes (x et y)
On peut ajouter des dimensions en jouant sur d’autres variables visuelles
Il faut s’assurer que la variable corresponde à ce qu’on veut montrer
L’exemple précédent cherche à distinguer entre catégories, la variation sur la couleur ou la forme est donc appropriée
Dans le cas d’une variable quantitative (absolue), on peut faire varier la taille pour montrer la quantité
Résultats du championnat de foot de Premier League (Ang.)
20 équipes jouant 2x contre chacune des autres (380 matchs, saison en cours, 367 matchs joués)
Données issues de https://fbref.com
Date Time Home HomeGoals AwayGoals Away
1 2022-08-05 20:00 Crystal Palace 0 2 Arsenal
2 2022-08-06 12:30 Fulham 2 2 Liverpool
3 2022-08-06 15:00 Tottenham 4 1 Southampton
4 2022-08-06 15:00 Newcastle Utd 2 0 Nott'ham Forest
5 2022-08-06 15:00 Leeds United 2 1 Wolves
6 2023-05-28 16:30 Brentford NA NA Manchester City
Date Time Home HomeGoals AwayGoals Away
1 2022-08-05 20:00 Crystal Palace 0 2 Arsenal
2 2022-08-06 12:30 Fulham 2 2 Liverpool
On a des données :
Commençons par les numériques en utilisant les buts pour en x et ceux contre en y
On peut dériver de nouvelles dimensions à partir des données à disposition
En se battant un peu avec les données, on obtient un jdd utilisable (= au format tidy)
On peut rajouter une dimension pour aider la lecture
Si l’équipe à dom. marque plus qu’elle n’encaisse, elle gagne
Dans le cas inverse, elle perd
Si les équipes ont un score égal, c’est un match nul
# A tibble: 3 × 4
HomeGoals AwayGoals freq rslt
<dbl> <dbl> <int> <chr>
1 0 0 22 nul
2 1 2 21 défaite
3 4 2 3 victoire
couleurs_rslt <- c("victoire" = "#00985f", "défaite" = "#e55e5b", "nul" = "#7b8288")
pl_22_23 |>
filter(! is.na(HomeGoals)) |>
group_by(HomeGoals, AwayGoals) |>
summarise(freq = n()) |>
mutate(rslt = case_when(
HomeGoals > AwayGoals ~ "victoire",
HomeGoals < AwayGoals ~ "défaite",
HomeGoals == AwayGoals ~ "nul")) |>
ggplot() +
geom_point(aes(HomeGoals, AwayGoals, size = freq, color = rslt)) +
coord_fixed(xlim = c(0,6),
ylim = c(0,6)) +
scale_color_manual(values = couleurs_rslt) +
labs(title = "Scores des matchs de Premier League") +
theme(plot.title = element_text(family = "Premier League"))Derniers ajustements cosmétiques :
# Préparation des fréquences et résultats
freq_scores_rslt <- pl_22_23 |>
filter(! is.na(HomeGoals)) |>
group_by(HomeGoals, AwayGoals) |>
summarise(freq = n()) |>
mutate(rslt = case_when(
HomeGoals > AwayGoals ~ "victoire",
HomeGoals < AwayGoals ~ "défaite",
HomeGoals == AwayGoals ~ "nul"))
# Calcul des infos supplémentaires
nb_matchs <- sum(freq_scores_rslt$freq)
nb_vict <- sum(freq_scores_rslt[freq_scores_rslt$rslt == "victoire", "freq"])
nb_def <- sum(freq_scores_rslt[freq_scores_rslt$rslt == "défaite", "freq"])
nb_nul <- sum(freq_scores_rslt[freq_scores_rslt$rslt == "nul", "freq"])
# Couleurs des rslts
couleurs_rslt <- c("victoire" = "#00985f", "défaite" = "#e55e5b", "nul" = "#7b8288")
freq_scores_rslt |>
ggplot() +
geom_segment(x = 0, y = 0, xend = 6, yend = 6, linewidth = 0.5, color = "grey85") +
geom_point(aes(HomeGoals, AwayGoals, size = freq, color = rslt)) +
geom_curve(aes(x = 4.55, y = 3.25, xend = 4.1, yend = 2.1),
arrow = arrow(length = unit(0.12, "inch")), size = 0.5,
color = "gray40", curvature = -0.2) +
annotate("text", x = 4.55, y = 3.4, label = "3 matchs ont fini à 4-2", size = 4, color = "gray40", hjust = 0.5) +
coord_fixed(xlim = c(0.5, 5.5),
ylim = c(0.5, 5.5)) +
scale_x_discrete(limits = c(0:6)) +
scale_y_discrete(limits = c(0:6)) +
scale_color_manual(values = couleurs_rslt) +
scale_size_area(breaks = c(max(freq_scores_rslt$freq), 21, 10, 5)) +
labs(title = "Scores des matchs de Premier League",
subtitle = str_glue("Saison 22/23 - {nb_matchs} matchs: ",
"<span style = 'color:#00985f;'>{nb_vict} victoires</span> et ",
"<span style = 'color:#e55e5b;'>{nb_def} défaites</span> ",
"à domicile, ",
"<span style = 'color:#7b8288;'>{nb_nul} nuls</span>"),
x = "Buts marqués à domicile",
y = "Buts encaissés à domicile",
size = "Matchs",
caption = "Données FBref.com | 2 matchs non affichés (9-0, 7-0)") +
theme_minimal() +
theme(text = element_text(family = "Century Gothic"),
plot.title = element_text(family = "Premier League"),
plot.subtitle = element_markdown(),
panel.grid.major = element_line(color = "gray95"),
legend.position = c(0.75, 0.77),
legend.background = element_rect(fill = alpha("white", 0.8), linetype = "blank"),
axis.title.x = element_text(margin = margin(10, 0, 0, 0)),
axis.title.y = element_text(margin = margin(0, 10, 0, 0)),
plot.caption = element_text(color = "gray65", margin = margin(10,0,0,0))) +
guides(color="none")Pour complexifier (et utiliser des petits multiples)
et…combinaisons des éléments précédents
couleurs_rslt <- c("victoire" = "#00985f", "défaite" = "#e55e5b", "nul" = "#7b8288")
leagues_22_23 <- rbind(pl_22_23, liga_22_23, seriea_22_23)
leagues_22_23 |>
group_by(Competition_Name, HomeGoals, AwayGoals) |>
summarise(freq = n()) |>
mutate(rslt = case_when(
HomeGoals > AwayGoals ~ "victoire",
HomeGoals < AwayGoals ~ "défaite",
HomeGoals == AwayGoals ~ "nul")) |>
ggplot() +
facet_wrap(~ Competition_Name, nrow = 1) +
geom_point(aes(HomeGoals, AwayGoals, size = freq, color = rslt)) +
coord_fixed(xlim = c(0.3, 5.5),
ylim = c(0.3, 5.5)) +
scale_x_discrete(limits = c(0:6)) +
scale_y_discrete(limits = c(0:6)) +
scale_color_manual(values = couleurs_rslt) +
labs(title = "Scores des matchs de championnats européens",
subtitle = "Saison 2022/23",
x = "Buts marqués à domicile",
y = "Buts encaissés à domicile") +
theme_minimal(base_size = 15) +
theme(legend.position = "none",
strip.text.x = element_text(face = "bold"),
text = element_text(family = "Century Gothic"),
axis.title.x = element_text(margin = margin(10, 0, 0, 0)),
axis.title.y = element_text(margin = margin(0, 10, 0, 0)),
axis.title = element_text(size = 10),
panel.spacing.x = unit(2, "lines"))couleurs_rslt <- c("victoire" = "#00985f", "défaite" = "#e55e5b", "nul" = "#7b8288")
pl_20_23 <- rbind(pl_22_23, pl_21_22, pl_20_21)
pl_20_23 |>
group_by(Season_End_Year, HomeGoals, AwayGoals) |>
summarise(freq = n()) |>
mutate(rslt = case_when(
HomeGoals > AwayGoals ~ "victoire",
HomeGoals < AwayGoals ~ "défaite",
HomeGoals == AwayGoals ~ "nul")) |>
ggplot() +
facet_wrap(~ Season_End_Year) +
geom_point(aes(HomeGoals, AwayGoals, size = freq, color = rslt)) +
coord_fixed(xlim = c(0.3, 5.5),
ylim = c(0.3, 5.5)) +
scale_x_discrete(limits = c(0:6)) +
scale_y_discrete(limits = c(0:6)) +
scale_color_manual(values = couleurs_rslt) +
labs(title = "Scores des matchs de Premier League",
subtitle = "Saisons 2020/21 à 2022/23",
x = "Buts marqués à domicile",
y = "Buts encaissés à domicile") +
theme_minimal(base_size = 15) +
theme(legend.position = "none",
strip.text.x = element_text(face = "bold"),
text = element_text(family = "Century Gothic"),
title = element_text(family = "Premier League"),
axis.title.x = element_text(margin = margin(10, 0, 0, 0)),
axis.title.y = element_text(margin = margin(0, 10, 0, 0)),
panel.spacing = unit(2, "lines"))rslt_equipes_pl <- data.frame(goal_for = numeric(), goal_against = numeric(), n = numeric(), team = numeric())
for (team in unique(pl_22_23$Home)){
freq_rslt_team <- pl_22_23 |>
filter((Home == team | Away == team) & ! is.na(HomeGoals)) |>
select(Home, HomeGoals, Away, AwayGoals) |>
mutate(goal_for = if_else(Home == team, HomeGoals, AwayGoals),
goal_against = if_else(Home == team, AwayGoals, HomeGoals)) |>
group_by(goal_for, goal_against) |>
summarise(n = n()) |>
mutate(team = team)
rslt_equipes_pl <- rbind(rslt_equipes_pl, freq_rslt_team)
}
classement_pl <- fb_season_team_stats("ENG", "M", 2023, "1st", "league_table")
ordre_equipes <- classement_pl |>
arrange(Rk) |>
pull(Squad)
couleurs_rslt <- c("victoire" = "#00985f", "défaite" = "#e55e5b", "nul" = "#7b8288")
rslt_equipes_pl |>
mutate(bp = goal_for, bc = goal_against, rslt = case_when(bp > bc ~ "victoire",
bp < bc ~ "défaite",
.default = "nul")) |>
dplyr::filter(team %in% ordre_equipes[c(1,2,3,4,10,11,12,18,19,20)]) |>
ggplot() +
facet_wrap(~ factor(team, levels = ordre_equipes), nrow = 2) +
geom_segment(x = 0, y = 0, xend = 6, yend = 6, linewidth = 0.4, color = "grey90") +
geom_point(aes(bp, bc, size = n, color = rslt)) +
scale_x_continuous(limits = c(0, 6), breaks = c(0:6)) +
scale_y_continuous(limits = c(0, 6), breaks = c(0:6)) +
scale_color_manual(values = couleurs_rslt) +
coord_fixed(xlim = c(0, 5.8),
ylim = c(0, 5.8), clip = "off") +
scale_size_area(max_size = 4) +
labs(title = "Scores d'équipes de Premier League",
subtitle = "Équipes classées 1, 2, 3, 4, 10 | 11, 12, 18, 19, 20",
x = "Buts marqués",
y = "Buts encaissés",
size = "Nombre \nde matchs") +
theme_minimal(base_size = 15) +
theme(panel.grid.minor = element_blank(),
panel.grid.major = element_line(color = "gray95"),
text = element_text(family = "Century Gothic"),
plot.title = element_text(color = "gray35"),
plot.subtitle = element_text(color = "gray65", size = 12),
axis.title = element_text(size = 6),
strip.text = element_text(size = 9, family = "Premier League", colour = "gray40"),
axis.text = element_text(size = 6),
axis.title.x = element_text(margin = margin(8, 0, 0, 0)),
axis.title.y = element_text(margin = margin(0, 5, 0, 0)),
axis.text.x = element_text(margin = margin(-4,0,0,0)),
panel.spacing.x = unit(1.5, "lines"),
legend.position = "none") +
guides(color="none")rslt_equipes_pl_20_23 <- data.frame(goal_for = numeric(), goal_against = numeric(), n = numeric(), team = numeric())
for (team in unique(pl_22_23$Home)){
freq_rslt_team <- pl_20_23 |>
filter((Home == team | Away == team) & ! is.na(HomeGoals)) |>
select(Season_End_Year, Home, HomeGoals, Away, AwayGoals) |>
mutate(goal_for = if_else(Home == team, HomeGoals, AwayGoals),
goal_against = if_else(Home == team, AwayGoals, HomeGoals)) |>
group_by(Season_End_Year, goal_for, goal_against) |>
summarise(n = n()) |>
mutate(team = team,
season = Season_End_Year)
rslt_equipes_pl_20_23 <- rbind(rslt_equipes_pl_20_23, freq_rslt_team)
}
couleurs_rslt <- c("victoire" = "#00985f", "défaite" = "#e55e5b", "nul" = "#7b8288")
rslt_equipes_pl_20_23 |>
mutate(bp = goal_for, bc = goal_against, rslt = case_when(bp > bc ~ "victoire",
bp < bc ~ "défaite",
.default = "nul")) |>
dplyr::filter(team %in% c("Newcastle Utd", "Brighton") & season %in% c(2021, 2022, 2023)) |>
ggplot() +
facet_grid(team ~ season) +
geom_segment(x = 0, y = 0, xend = 6, yend = 6, linewidth = 0.4, color = "grey90") +
geom_point(aes(bp, bc, size = n, color = rslt)) +
scale_x_continuous(limits = c(0, 6), breaks = c(0:6)) +
scale_y_continuous(limits = c(0, 6), breaks = c(0:6)) +
scale_color_manual(values = couleurs_rslt) +
coord_fixed(xlim = c(0, 5.8),
ylim = c(0, 5.8), clip = "off") +
scale_size_area(max_size = 4) +
labs(title = "Évolution des résultats de Newcastle Utd et Brighton",
x = "Buts marqués",
y = "Buts encaissés",
size = "Nombre \nde matchs") +
theme_minimal(base_size = 15) +
theme(panel.grid.minor = element_blank(),
panel.grid.major = element_line(color = "gray95"),
text = element_text(family = "Century Gothic"),
plot.title = element_text(color = "gray25", size = 14),
axis.title = element_text(size = 6),
strip.text = element_text(size = 9, family = "Premier League", colour = "gray40"),
axis.text = element_text(size = 6),
panel.spacing = unit(1, "lines"),
legend.position = "none") +
guides(color="none")Avec R, il est possible d’obtenir le même résultat
On préfère des petits multiples pour comparer efficacement
Également en valeurs relatives
Commencez par choisir deux variables numériques (avec un lien réfléchi)
Pensez aux dimensions qu’il est possible d’ajouter (couleur, taille, etc.)
Attention à la contrainte des petits multiples
Il faudra généralement une dimension temporelle ou catégorielle pour les utiliser
tidySi vos données sont organisées de façon régulière (méthodique), il est possible d’utiliser une des fonctions :
pivot_longer(), pour transformer les colonnes et ajouter des lignespivot_wider(), fonction inversePlus d’informations dans ce chapitre de livre consacré au tidying des données.